package com.woniu.login.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.common.dto.LoginDto;
import com.woniu.common.entity.AdmAccount;
import com.woniu.common.entity.AdmEmployee;
import com.woniu.common.entity.Result;
import com.woniu.login.configuration.JwtUtils;
import com.woniu.login.mapper.AccountMapper;
import com.woniu.login.mapper.LoginMapper;
import com.woniu.login.service.LoginService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;

@Service
public class LoginServiceShiroImpl implements LoginService {
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    LoginMapper loginMapper;
    @Autowired
    AccountMapper accountMapper;
    @Autowired
    RabbitTemplate rabbitTemplate;
    //  员工登录
    @Override
    public Result admlogin(LoginDto loginDto, HttpServletResponse response) {
        //  通过key从redis获取存储验证码
        String verifycode = (String) redisTemplate.opsForValue().get("code:" + loginDto.getUuid());
        //  判断验证码是否正确
        if (loginDto.getVerifyCode() == null || !verifycode.equals(loginDto.getVerifyCode())) {
            return Result.fail("验证码错误！");
        }else if (verifycode.equals(loginDto.getVerifyCode())) {
            try{
            //  创建用户名密码token
            UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginDto.getNumber(), loginDto.getPassword());
            System.out.println("用户名密码token："+usernamePasswordToken);
            //  获取subject
            Subject subject = SecurityUtils.getSubject();
            //  登录
            subject.login(usernamePasswordToken);
            //  获取登录用户
            AdmEmployee admEmployee = loginMapper.selectOne(new QueryWrapper<AdmEmployee>().eq("number", subject.getPrincipal()));
            //  生成token
            String salt = "12345";  //  设置密钥盐
            String newToken = JwtUtils.sign(loginDto.getNumber(), salt, 3600);
            //  将token存入redis
            redisTemplate.opsForValue().set("token:" + loginDto.getNumber(), newToken);
            //  设置key为x-auth-token的数据可以被前端JavaScript获取
            response.setHeader("Access-Control-Expose-Headers", "x-auth-token, number");
            //  将token存入响应头
            response.setHeader("x-auth-token", newToken);
            response.setHeader("userid", loginDto.getId());
            return Result.ok("登录成功！");
            }catch (AuthenticationException e) {
                return Result.fail("用户名或密码错误！");
//                throw e;
            } catch (IllegalStateException e ){
                return Result.fail("请登录！");
            }catch (Exception e) {
                throw e;
            }
        }
        return Result.fail("登录失败！");
    }
    @Override
    public AdmEmployee getAdmEmployeeByNumber(String Number) {
        return loginMapper.selectOne(new QueryWrapper<AdmEmployee>().eq("number", Number));
    }

    //  获取上次token生成时的salt值和登录用户信息
    public AdmEmployee getJwtTokenInfo(String number) {
        String salt = "12345";
        AdmEmployee employee = getAdmEmployeeByNumber(number);
        return employee;
    }
    //  向邮箱发送验证码
    @Override
    public Result sendEmail(String email,int code) {
        String message = email + ";" + code;
        rabbitTemplate.convertAndSend("verifyExchange","verifymail", message);
        return null;
    }
    // 添加员工
    @Override
    public void addEmployee(AdmEmployee admEmployee) {
        loginMapper.insert(admEmployee);
        AdmAccount admAccount = new AdmAccount();
        admAccount.setAaname(admEmployee.getUsername());
        admAccount.setAanumber(admEmployee.getNumber());
        admAccount.setAapassword(admEmployee.getPassword());
        admAccount.setAatype("员工");
        accountMapper.insert(admAccount);
    }
}
